package cn.hinglo.gameclaw.admin.service;

import cn.hinglo.gameclaw.admin.dao.ClawDao;
import cn.hinglo.gameclaw.data.entity.Result;
import cn.hinglo.gameclaw.data.exception.ResultException;
import cn.hinglo.gameclaw.data.utils.CommonUtils;
import cn.hinglo.gameclaw.data.utils.FieldUtils;
import cn.hinglo.gameclaw.data.utils.FileImageUtils;
import cn.hinglo.gameclaw.data.utils.ResultUtils;
import cn.hinglo.gameclaw.im.bean.ChatRoom;
import cn.hinglo.gameclaw.im.bean.LiveRoom;
import cn.hinglo.gameclaw.im.service.ChatRoomService;
import cn.hinglo.gameclaw.im.service.LiveRoomService;
import cn.hinglo.gameclaw.user.bean.Claw;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.List;
import java.util.Map;

import static cn.hinglo.gameclaw.data.utils.FieldUtils.*;


/**
 * @createTime: 2018/1/2
 * @author: HingLo
 * @description: 娃娃机管理的服务层
 */
@Service
@Slf4j
@CacheConfig(cacheNames = "claw")
public class ClawService {
    private final ClawDao clawDao;
    private final ChatRoomService chatRoomService;
    private final LiveRoomService liveRoomService;

    @Autowired
    public ClawService(ClawDao clawDao, ChatRoomService chatRoomService, LiveRoomService liveRoomService) {
        this.clawDao = clawDao;
        this.chatRoomService = chatRoomService;
        this.liveRoomService = liveRoomService;
    }

    /**
     * 根据指定的类型查询娃娃机器
     *
     * @param status 状态
     * @return 返回结果值
     */
    public Result listClawService(int status) {
        // 只能是指定的类型
        if (status == CLAW_STATUS_0 || status == CLAW_STATUS_1 || status == CLAW_STATUS_2 || status == CLAW_STATUS_3) {
            //组合查询的条件
            Claw claw = new Claw().setStatus(status);
            return ResultUtils.success(clawDao.select(claw));
        } else if (status == CLAWS_TATUS_4) {
            return ResultUtils.success(clawDao.selectAll());
        }
        return ResultUtils.error("查询类型不正确");

    }

    /**
     * 添加娃娃机
     *
     * @param claw 娃娃机对象
     * @return 添加结果
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @CacheEvict(allEntries = true)
    public Result addClawService(Claw claw, MultipartFile image) {

        //检测编号是否存在
        int id = claw.getId();
        if (clawDao.selectByPrimaryKey(id) != null) {
            return ResultUtils.error("该娃娃机的编号已经存在");
        }
        String fileName = FileImageUtils.createFileNameUtils(image);
        if (FileImageUtils.saveImageUtils(image, fileName, IMAGE_3)) {
            claw.setDate(new Date());
            //设置图片名字
            claw.setHeader(fileName);
            //**************创建聊天室的****************//
            ChatRoom chatRoom = chatRoomService.createRoomBeanService(FieldUtils.IM_ACCOUNT_ADMIN, claw.getName());
            if (chatRoom == null) {
                return ResultUtils.error("聊天室创建失败");
            }
            claw.setRoomId(chatRoom.getRoomid());
            //****************** 创建直播频道**************//
            LiveRoom liveRoom1 = liveRoomService.createBeanService(claw.getName() + "_1", FieldUtils.LIVE_PULL_TYPE);
            LiveRoom liveRoom2 = liveRoomService.createBeanService(claw.getName() + "_2", FieldUtils.LIVE_PULL_TYPE);
            if (liveRoom1 == null || liveRoom2 == null) {
                return ResultUtils.error("直播频道创建失败");
            }
            claw.setLive1(liveRoom1.getCid());
            claw.setLive2(liveRoom2.getCid());

            //***********保存信息******************//
            if (liveRoomService.saveService(liveRoom1, liveRoom2) && chatRoomService.saveService(chatRoom) && clawDao.insert(claw) == 1) {
                return ResultUtils.success();
            } else {
                throw new RuntimeException("娃娃机创建爱失败");
            }
        }
        return ResultUtils.error("图片上传失败");

    }

    /**
     * 通过娃娃机的编号来查询娃娃机的唯一信息
     *
     * @param id 娃娃机的编号
     * @return 返回娃娃机对象
     */
    @Cacheable(key = "#id")
    public Claw findByIdClawService(Integer id) {
        return clawDao.selectByPrimaryKey(id);
    }

    /**
     * 删除娃娃机
     *
     * @param id 娃娃机的唯一编号
     * @return 删除的结果
     */
    @CacheEvict(allEntries = true)
    public Result deleteClawService(int id) {
        return clawDao.deleteByPrimaryKey(id) > 0 ? ResultUtils.success() : ResultUtils.error("娃娃机删除失败");
    }


    /***
     * 修改娃娃机的展示图
     * @param id 娃娃机的唯一id
     * @param image 展示图的图片对象
     * @return 修改结果
     */
    @CacheEvict(allEntries = true)
    public Result updateClawHeaderService(Integer id, MultipartFile image) {
        //检测娃娃机是否在未启用的状态
        if (checkClawStatus(id)) {
            //生成文件名称
            String fileName = FileImageUtils.createFileNameUtils(image);
            //保存图片到本地文件
            if (FileImageUtils.saveImageUtils(image, fileName, IMAGE_3)) {
                //组合条件
                Claw claw = new Claw().setHeader(fileName).setId(id);
                return clawDao.updateByPrimaryKeySelective(claw) > 0 ? ResultUtils.success() : ResultUtils.error("展示图修改失败");
            }
        }
        return ResultUtils.error("该娃娃机不是在未启用的状态,无法更改信息");

    }


    /**
     * 修改娃娃机的状态
     * <p>修改了状态就直接删除娃娃机的缓存信息</p>
     *
     * @param id     娃娃机的唯一id
     * @param status 修改的娃娃机状态
     * @return 娃娃机的唯一id
     */
    @CacheEvict(allEntries = true)
    public Result updateClawStatusService(Integer id, int status) {
        checkClawIsExistence(id);
        if (status == CLAW_STATUS_0 || status == CLAW_STATUS_1 || status == CLAW_STATUS_2 || status == CLAW_STATUS_3) {
            Claw claw = new Claw().setId(id).setStatus(status);
            return clawDao.updateByPrimaryKeySelective(claw) > 0 ? ResultUtils.success() : ResultUtils.error("修改失败");
        }
        return ResultUtils.error("指定的状态不存在的");
    }

    /**
     * 修改娃娃机器的其他信息
     * <spa>娃娃机修改信息必须保证值是正确的，并且该娃娃机的状态是处于一个“未启用”状态</spa>
     *
     * @param id    娃娃机的唯一编号
     * @param value 修改的值
     * @param type  修改信息的类型
     * @return 返回修改结果
     */
    @CacheEvict(allEntries = true)
    public Result updateOtherInfoService(int id, String value, int type) {
        //判断娃娃机是否处于启用状态，并且在修改的值正确
        if (StrUtil.isNotBlank(value) && checkClawStatus(id)) {
            int result;
            Claw claw = new Claw().setId(id);
            switch (type) {
                case 1:
                    //修改娃娃机的名字
                    claw.setName(value);
                    result = clawDao.updateByPrimaryKeySelective(claw);
                    break;
                case 2:
                    //修改娃娃机的抓一次用的金币
                    if (!Validator.isNumber(value)) {
                        return ResultUtils.error("修改金额是非数字");
                    } else {
                        claw.setGold(Integer.valueOf(value));
                        result = clawDao.updateByPrimaryKeySelective(claw);
                    }
                    break;
                default:
                    return ResultUtils.error("修改的指定类型不存在");
            }
            return result > 0 ? ResultUtils.success() : ResultUtils.error("修改失败");

        }
        return ResultUtils.error("修改的值不能为空");
    }


    /**
     * 检测该娃娃机编号的娃娃机是否存在
     *
     * @param id 娃娃机的唯一id
     */
    private void checkClawIsExistence(int id) {
        Claw claw = findByIdClawService(id);
        if (claw == null) {
            throw new ResultException(-1, "该娃娃机不存在");
        }
    }

    /**
     * 检测娃娃机的状态
     *
     * @param id 娃娃机的唯一id
     * @return 返回娃娃机的指定状态
     */
    private boolean checkClawStatus(int id) {
        Claw claw = findByIdClawService(id);
        if (claw == null) {
            throw new ResultException(-1, "该娃娃机不存在");
        } else {
            return CLAW_STATUS_0 == claw.getStatus();
        }
    }

    /**
     * 大神榜数据
     *
     * @return
     */
    public List<?> okamiListService() {
        Date date = new Date();
        Date start = DateUtil.beginOfWeek(date);
        Date end = DateUtil.endOfWeek(date);
        List<Map<String, Object>> list = clawDao.okamiListDao(start, end);
        list.forEach(x -> {
            String header = (String) x.get("header");
            if (!StrUtil.startWith(header, FieldUtils.PREFIX)) {
                x.put("header", CommonUtils.imgInstall(header, FieldUtils.IMAGE_4));
            }
        });
        return list;
    }
}
